#pragma once

class bObject;
class Level;

struct bInitData
{
	bInitData() :
		mass(1.0f),
		restitution(1.0f),
		friction(1.5f),
		angularDamping(0.5f),
		linearDamping(0.1f),
		rollingFriction(1.0f)
	{
	}

	glm::vec3	position;
	glm::vec3	intertia;
	glm::quat	rotation;
	float		mass;
	float		restitution;
	float		friction;
	float		angularDamping;
	float		linearDamping;
	float		rollingFriction;
};

class WorldMgr
{
public:
	WorldMgr();
	~WorldMgr();

	void				InitWorldMgr();
	void				SetGravity(const glm::vec3& gravity);

	void				AddBorderPlane(const std::string& name, const glm::vec3& normal, float constant);
	void				AddObject(const std::string& name, bObject* object);

	void				RenderOpaque();
	void				CalculatePhysics();

	btDiscreteDynamicsWorld* GetWorld();
	Level*				GetLoadedLevel();
	void				LoadLevel(const std::string& name);

private:
	btDbvtBroadphase*						m_bullet_broadphase;
	btDefaultCollisionConfiguration*		m_bullet_collisionConfiguration;
	btCollisionDispatcher*					m_bullet_dispatcher;
	btSequentialImpulseConstraintSolver*	m_bullet_solver;
	btDiscreteDynamicsWorld*				m_bullet_dynamicsWorld;

	std::map<std::string, bObject*>		m_nameWithObject;

	ITimer*		m_timer;
	IMutex*		m_worldSync_mutex;

	Level*		m_loadedLevel;
};

